package cn.cutie.clotconfig.client.config;

import cn.cutie.clotconfig.client.repository.ClotRepository;
import cn.cutie.clotconfig.client.repository.ClotRepositoryChangeListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author: Cutie
 * @CreateDate: 2024/5/10 20:18
 * @Version: 0.0.1
 */
@Slf4j
public class ClotConfigServiceImpl implements ClotConfigService {

    ApplicationContext applicationContext;

    // 远程访问配置中心返回
    Map<String, String> config;

    public ClotConfigServiceImpl(ApplicationContext applicationContext, Map<String, String> config) {
        this.applicationContext = applicationContext;
        this.config = config;
    }

    @Override
    public String[] getPropertyNames() {
        return this.config.keySet().toArray(new String[0]);
    }

    @Override
    public String getProperty(String name) {
        return this.config.get(name);
    }

    @Override
    public void onChange(ClotRepositoryChangeListener.ChangeEvent changeEvent) {
        Set<String> keys = calcChangedKeys(this.config, changeEvent.config());
        if (keys.isEmpty()){
            log.info("[CLOTCONFIG] calcChangedKeys return empty, ingnore updates");
            return;
        }
        this.config = changeEvent.config();
        if (config != null) {
            System.out.println("[CLOTCONFIG] fire an EnvironmentChangeEvent with keys:" + keys);
            applicationContext.publishEvent(new EnvironmentChangeEvent(keys));
        }
    }

    private Set<String> calcChangedKeys(Map<String, String> oldConfigs, Map<String, String> newConfigs) {
        // 当前的数据和之前的数据对比
        if (oldConfigs.isEmpty()) return newConfigs.keySet();
        if (newConfigs.isEmpty()) return oldConfigs.keySet();
        Set<String> news = newConfigs.keySet().stream()
                .filter(key -> !newConfigs.get(key).equals(oldConfigs.get(key)))
                .collect(Collectors.toSet());
        oldConfigs.keySet().stream().filter(key -> !newConfigs.containsKey(key)).forEach(news::add);
        return news;
    }

}
